package io.github.wppli.trigger.http;

import cc.jq1024.middleware.token.service.ITokenService;
import io.github.wppli.domain.recommond.model.entity.PostsContentEntity;
import io.github.wppli.domain.recommond.model.entity.ProductEntity;
import io.github.wppli.domain.recommond.model.entity.RecommendUserEntity;
import io.github.wppli.domain.recommond.rservice.SparkRecommendationService;
import io.github.wppli.domain.recommond.rservice.AbstractProductRecommendService;
import io.github.wppli.domain.recommond.rservice.text.ContentRecommenderService;
import io.github.wppli.domain.recommond.rservice.AbstractUserRecommendService;
import io.github.wppli.types.exception.AppException;
import io.github.wppli.types.model.Response;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author li--jiaqiang 2025−03−12
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/recommend/")
@CrossOrigin(value = {"${app.config.cross-origin:http://116.198.239.101:3000/}", "http://localhost:3000/"})
public class RecommendController {

    private final ITokenService tokenService;
    private final AbstractProductRecommendService recommendProductService;
    private final AbstractUserRecommendService userRecommendService;
    private final SparkRecommendationService sparkRecommendationService;
    private final ContentRecommenderService contentRecommenderService;

    /**
     * 获取协同过滤推荐的商品列表
     * @param authorization 用户token
     * @return  推荐的商品列表
     */
    @GetMapping("/user/product")
    public Response<List<ProductEntity>> getRecommendUserCF(@RequestHeader("Authorization") String authorization)  {
        try {
            Long startTime = System.currentTimeMillis();

            String authToken = authorization.replace("Bearer ", "");
            Long userId = Long.parseLong(tokenService.decode(authToken).getSubject());
            List<ProductEntity> recommendations = recommendProductService.getRecommendEntitiesByUserCF(userId);
            Long endTime = System.currentTimeMillis();
            log.info("Recommend-UserCF Product Time: {}", endTime - startTime);
            return Response.ok(recommendations);
        } catch (AppException exception) {
            log.error("AppException: ",exception);
            return Response.<List<ProductEntity>>builder()
                    .code(exception.getCode())
                    .info(exception.getInfo())
                    .build();
        } catch (Exception exception) {
            log.error("Exception: ",exception);
            return Response.systemError();
        }
    }

    /**
     * 获取协同过滤推荐的商品列表
     * @param authorization 用户token
     * @return  推荐的商品列表
     */
    @GetMapping("/item/product")
    public Response<List<RecommendUserEntity>> getRecommendItemCF(@RequestHeader("Authorization") String authorization)  {
        try {
            Long startTime = System.currentTimeMillis();

            String authToken = authorization.replace("Bearer ", "");
            Long userId = Long.parseLong(tokenService.decode(authToken).getSubject());
            List<RecommendUserEntity> recommendations = userRecommendService.getRecommendEntityByItemCF(userId);
            Long endTime = System.currentTimeMillis();
            log.info("Recommend-ItemCF Product Time: {}", endTime - startTime);
            return Response.ok(recommendations);
        } catch (AppException exception) {
            log.error("AppException: ",exception);
            return Response.<List<RecommendUserEntity>>builder()
                    .code(exception.getCode())
                    .info(exception.getInfo())
                    .build();
        } catch (Exception exception) {
            log.error("Exception: ",exception);
            return Response.systemError();
        }
    }


    /**
     * 获取协同过滤推荐的商品列表
     * @param authorization 用户token
     * @return  推荐的商品列表
     */
    @GetMapping("/spark")
    public Response<List<ProductEntity>> getSparkRecommendations(@RequestHeader("Authorization") String authorization)  {
        try {
            Long startTime = System.currentTimeMillis();
            String authToken = authorization.replace("Bearer ", "");
            Long userId = Long.parseLong(tokenService.decode(authToken).getSubject());
            List<ProductEntity> recommendations = sparkRecommendationService.getRecommendations(userId);
            Long endTime = System.currentTimeMillis();
            log.info("Spark Recommendation Time: {}", endTime - startTime);
            return Response.ok(recommendations);
        } catch (AppException exception) {
            log.error("AppException: ",exception);
            return Response.<List<ProductEntity>>builder()
                    .code(exception.getCode())
                    .info(exception.getInfo())
                    .build();
        } catch (Exception exception) {
            log.error("Exception: ",exception);
            return Response.systemError();
        }
    }

    /**
     * 根据用户行为推荐内容
     * @param authorization 用户 token
     * @param topN 推荐数量
     * @return 推荐的内容列表
     */
    @GetMapping("/user/content")
    public Response<List<PostsContentEntity>> recommendByUserId(
            @RequestHeader("Authorization") String authorization,
            @RequestParam(defaultValue = "10") int topN) {
        try {
            Long startTime = System.currentTimeMillis();
            String authToken = authorization.replace("Bearer ", "");
            Long userId = Long.parseLong(tokenService.decode(authToken).getSubject());
            List<PostsContentEntity> postsContentEntities = contentRecommenderService.recommendContent(userId, topN);
            Long endTime = System.currentTimeMillis();
            log.info("content recommendByUserId Time: {}", endTime - startTime);
            return Response.ok(postsContentEntities);
        } catch (AppException exception) {
            log.error("AppException: ",exception);
            return Response.<List<PostsContentEntity>>builder()
                    .code(exception.getCode())
                    .info(exception.getInfo())
                    .build();
        } catch (Exception exception) {
            log.error("Exception: ",exception);
            return Response.systemError();
        }

    }

    /**
     * 实时搜索推荐
     * @param keywords 搜索关键词
     * @param topN 推荐数量
     * @return 推荐的内容列表
     */
    @GetMapping("/search/content")
    public Response<List<PostsContentEntity>> recommendByKeywords(@RequestParam String keywords, @RequestParam(defaultValue = "10") int topN) {
        try {
            Long startTime = System.currentTimeMillis();
            List<PostsContentEntity> postsContentEntities = contentRecommenderService.recommendContent(keywords, topN);
            Long endTime = System.currentTimeMillis();
            log.info("content recommendByKeywords Time: {}", endTime - startTime);

            return Response.ok(postsContentEntities);
        } catch (AppException exception) {
            log.error("AppException: ",exception);
            return Response.<List<PostsContentEntity>>builder()
                    .code(exception.getCode())
                    .info(exception.getInfo())
                    .build();
        } catch (Exception exception) {
            log.error("Exception: ",exception);
            return Response.systemError();
        }
    }

    /**
     * 获取热门推荐的商品列表
     */
    @GetMapping("/hot/products")
    public Response<List<ProductEntity>> getHotRecommendations() {
        try {
            List<ProductEntity> topHotProducts = recommendProductService.getTopHotProducts();
            return Response.ok(topHotProducts);
        } catch (AppException exception) {
            log.error("AppException: ",exception);
            return Response.<List<ProductEntity>>builder()
                    .code(exception.getCode())
                    .info(exception.getInfo())
                    .build();
        } catch (Exception exception) {
            log.error("Exception: ",exception);
            return Response.systemError();
        }
    }

}